package zust.javaee.service.Impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import zust.javaee.dao.hibernate.BaseDao;
import zust.javaee.dto.AjaxReturn;
import zust.javaee.dto.SessionInfo;
import zust.javaee.dto.SignCorporDto;
import zust.javaee.dto.activity.ActivityDto2;
import zust.javaee.dto.adminadd.PlayerAddDto;
import zust.javaee.dto.adminadd.ReqFormAddDto;
import zust.javaee.dto.announcement.AnnouncementDto;
import zust.javaee.dto.announcement.AnnouncementDto2;
import zust.javaee.dto.corporation.CorporationDto;
import zust.javaee.dto.player.PlayerLoginedDto;
import zust.javaee.dto.player.PlayerRegisterDto;
import zust.javaee.entity.*;
import zust.javaee.enums.FormStatusEnum;
import zust.javaee.enums.player.PlayerStatusEnum;
import zust.javaee.enums.player.PlayerTypeEnum;
import zust.javaee.service.PlayerService;
import zust.javaee.util.EmailUtil;
import zust.javaee.util.MD5Util;
import zust.javaee.util.StrUtil;

import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by liy on 2017/1/4.
 */
@Service
@Transactional
public class PlayerServiceImpl extends BaseServiceImpl<Tplayer> implements PlayerService {

    @Autowired
    private BaseDao<Tplayer> playerDao;

    @Autowired
    private BaseDao<Tcorporation> corporationDao ;

    @Autowired
    private BaseDao<Tmember> memberDao ;

    @Autowired
    private BaseDao<Tactivity> activityDao ;

    @Autowired
    private BaseDao<Tannouncement> annDao;

    @Autowired
    private BaseDao<TrequisitionForm> reqFormDao ;


    @Autowired
    private BaseDao<TsignupCorporation> signupCorporDao;

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public AjaxReturn<PlayerLoginedDto> doLogin(String sId, String password, HttpSession session) {
        if (countPlayerByStudentId(sId) < 1) {
            return new AjaxReturn<>(false, "用户名不存在");
        } else {
            /**  main  */
            try {
                Tplayer tplayer = getPlayerByStudentId(sId);
                if (tplayer.getPassword().equals(password) || MD5Util.validPassword(password, tplayer.getPassword())) {
                    //status 进行判断
                    switch (PlayerStatusEnum.stateOf(tplayer.getStatus())) {
                        case AVAILABLE:
                            //成功通过验证
                            PlayerLoginedDto playerLoginedDto = new PlayerLoginedDto();
                            SessionInfo sessionInfo = new SessionInfo(tplayer);
                            System.out.println(sessionInfo.getPlayerName()+"---1");
                            session.setAttribute("sessionInfo", sessionInfo);

                            BeanUtils.copyProperties(tplayer, playerLoginedDto);
                            if(tplayer.getBirth() != null)
                                playerLoginedDto.setBirthStr(sdf.format(tplayer.getBirth()));
                            session.setAttribute("playData", playerLoginedDto);

                            System.out.println(playerLoginedDto.getName());
                            return new AjaxReturn<>(true, "登陆成功", playerLoginedDto);
                        case CHECKING:
                            return new AjaxReturn<>(false, "未通过邮箱验证");
                        case QUIT:
                            return new AjaxReturn<>(false, "该用户已停用");
                        case DELETED:
                            return new AjaxReturn<>(false, "该用户已删除");
                    }

                } else {
                    return new AjaxReturn<>(false, "密码错误");
                }
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return new AjaxReturn<>(false, "Exception");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return new AjaxReturn<>(false, "Exception");
            }
        }
        return new AjaxReturn<>(false, "服务器繁忙");

    }



    @Override
    public AjaxReturn doRegister(PlayerRegisterDto playerRegisterDto) {
        if (StrUtil.hasEmpty(playerRegisterDto.getStudentId(),
                playerRegisterDto.getEmail(), playerRegisterDto.getPassword())) {
            return new AjaxReturn(false, "信息不完整");
        }else if (countPlayerByStudentId(playerRegisterDto.getStudentId()) > 0) {
            return new AjaxReturn(false, "用户名已存在");
        } else {
            /**   main   */
            try {
                Tplayer tplayer = new Tplayer();
                BeanUtils.copyProperties(playerRegisterDto, tplayer);
                tplayer.setPassword(MD5Util.getEncryptedPwd(playerRegisterDto.getPassword()));
                tplayer.setType(PlayerTypeEnum.REGISTER.getType());
                tplayer.setCorporationNum(0);
                tplayer.setStatus(PlayerStatusEnum.CHECKING.getStatus());
                tplayer.setPhoto("/media/img/player/initial.png");

                //邮箱验证码
                String npSalt = MD5Util.getEncryptedPwd(playerRegisterDto.getStudentId()+playerRegisterDto.getPassword());
                tplayer.setPwdSalt(npSalt);

                playerDao.save(tplayer);

                //返回值
                Tplayer newtplayer = getPlayerByStudentId(tplayer.getStudentId());
                PlayerLoginedDto playerLoginedDto = new PlayerLoginedDto();
                BeanUtils.copyProperties(newtplayer, playerLoginedDto);

                //邮箱注册
                try{
                    EmailUtil.SendRegisterEmail(playerRegisterDto.getEmail(), npSalt, newtplayer.getId());
                } catch (Exception e) {
                    e.printStackTrace();
                    playerDao.delete(newtplayer);
                    return new AjaxReturn(false, "请检查邮件是否正确");
                }
                return new AjaxReturn<>(true, "注册成功", playerLoginedDto);

            } catch (Exception e) {
                e.printStackTrace();
                return new AjaxReturn(false, "Exception");
            }
            /**   main end   */
        }
    }

    @Override
    public AjaxReturn activate(Integer id, String secret) {
        Tplayer tplayer = playerDao.get(Tplayer.class, id);
        if (tplayer.getPwdSalt() == null || tplayer.getPwdSalt().length() == 0)
            return new AjaxReturn(false, "该用户已通过验证");
        if (tplayer.getPwdSalt().equals(secret)){
            tplayer.setPwdSalt(null);
            tplayer.setStatus(PlayerStatusEnum.AVAILABLE.getStatus());
            playerDao.update(tplayer);
            return new AjaxReturn(true, "验证成功");
        }
        else
            return new AjaxReturn(false, "验证失败");
    }

    @Override
    public AjaxReturn signUpCorpor(Integer playerId, Integer corporId, ReqFormAddDto reqFormAddDto) {
        try {
            Tplayer tplayer = playerDao.get(Tplayer.class, playerId);
            Tcorporation tcorporation = corporationDao.get(Tcorporation.class, corporId);
            TrequisitionForm trequisitionForm = new TrequisitionForm();
            BeanUtils.copyProperties(reqFormAddDto, trequisitionForm);
            trequisitionForm.setRequisitionTime(new Date());
            trequisitionForm.setStatus(FormStatusEnum.CHECKING.getStatus());
            trequisitionForm.setTplayer(tplayer);
            trequisitionForm.setTcorporation(tcorporation);
            reqFormDao.save(trequisitionForm);
            return new AjaxReturn(true, "申请成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new AjaxReturn(false, "申请失败，信息不完整");
        }
    }

    @Override
    public AjaxReturn<List<CorporationDto>> getOnePlayerCorpor(Integer playerId) {
        List<Tmember> tmembers = memberDao.find("from Tmember l where l.tplayer.id = "+playerId);
        if (tmembers.size() <= 0)
            return new AjaxReturn<>(true, "没有加入社团");
        else {
            List<CorporationDto> cors = new ArrayList<>();
            for (Tmember tmember : tmembers) {
                Tcorporation tcorporation = corporationDao.get(Tcorporation.class, tmember.getTcorporation().getId());
                CorporationDto cor = new CorporationDto();
                BeanUtils.copyProperties(tcorporation, cor);
                cors.add(cor);
            }
            return new AjaxReturn<>(true, "加载完成", cors);
        }

    }

    @Override
    public AjaxReturn<List<ActivityDto2>> getOnePlayerActivity(Integer playerId) {
        List<Tmember> tmembers = memberDao.find("from Tmember l where l.tplayer.id = "+playerId);
        if (tmembers.size() <= 0)
            return new AjaxReturn<>(true, "没有参加的活动");
        else {
            List<ActivityDto2> acDtos = new ArrayList<>();
            for (Tmember tmember : tmembers) {
//                Tcorporation tcorporation = corporationDao.get(Tcorporation.class, tmember.getTcorporation().getId());
                Tactivity tactivity = activityDao.get(
                        "from Tactivity l where l.tcorporation.id ="+tmember.getTcorporation().getId());
                ActivityDto2 ac = new ActivityDto2();
                ac.setBeginTimeStr(sdf.format(tactivity.getBeginTime()));
                ac.setEndTimeStr(sdf.format(tactivity.getEndTime()));
                BeanUtils.copyProperties(tactivity, ac);
                acDtos.add(ac);
            }
            if (acDtos.size() <= 0)
                return new AjaxReturn<>(true, "没有参加的活动");
            else
                return new AjaxReturn<>(true, "加载完成", acDtos);
        }
    }

    @Override
    public AjaxReturn<List<AnnouncementDto2>> getOnePlayerAnn(Integer playerId) {
        List<Tmember> tmembers = memberDao.find("from Tmember l where l.tplayer.id = "+playerId);
        if (tmembers.size() <= 0)
            return new AjaxReturn<>(true, "没有加入社团");
        else {
            List<AnnouncementDto2> anns = new ArrayList<>();
            for (Tmember tmember : tmembers) {
                Tannouncement tann = annDao.get("from Tannouncement l where l.tcorporation.id = "
                        + tmember.getTcorporation().getId());
                if (tann != null) {
                    AnnouncementDto2 ann = new AnnouncementDto2();
                    BeanUtils.copyProperties(tann, ann);
                    anns.add(ann);
                }
            }
            if (anns.size() > 0)
                return new AjaxReturn<>(true, "加载完成", anns);
            else
                return new AjaxReturn<>(true, "没有公告");
        }
    }

    @Override
    public void upadtePlayer(Integer playerId, PlayerLoginedDto playerLoginedDto){
        Tplayer tplayer = playerDao.get(Tplayer.class, playerId);
        BeanUtils.copyProperties(playerLoginedDto, tplayer);
        try {
            tplayer.setBirth(sdf.parse(playerLoginedDto.getBirthStr()));
            playerDao.save(tplayer);
        }catch (ParseException e) {
            e.printStackTrace();
        }
    }

    @Override
    public AjaxReturn createCorporation(Integer playerId, SignCorporDto signCorporDto) {
        TsignupCorporation tsignupCorporation = new TsignupCorporation();
        Tplayer tp = playerDao.get(Tplayer.class, playerId);
        BeanUtils.copyProperties(signCorporDto, tsignupCorporation);
        tsignupCorporation.setTplayer(tp);
        tsignupCorporation.setStatus((short) 0);
        signupCorporDao.save(tsignupCorporation);
        return new AjaxReturn(true, "添加成功");
    }

    @Override
    public boolean checkExitPlayer(Integer studentId) {
        String hql = "select count(*) from Tplayer l where l.studentId = " + studentId;
        return playerDao.count(hql) >= 1;
    }

    @Override
    public AjaxReturn checkJoinCorporation(Integer playerId, Integer corporId) {
        if (playerId == null || corporId == null)
            return new AjaxReturn(false, "存在空参数");
        else {

        }
        return null;
    }

    @Override
    public AjaxReturn<List<PlayerLoginedDto>> getOneCorporAllPlayer(Integer corporId) {
        List<Tmember> tmembers = memberDao.find("from Tmember l where l.tcorporation.id = "+corporId);
        if (tmembers.size() <= 0)
            return new AjaxReturn<>(true, "没成员");
        else {
            List<PlayerLoginedDto> players = new ArrayList<>();
            for (Tmember tmember : tmembers) {
                Tplayer tplayer = playerDao.get(Tplayer.class, tmember.getTplayer().getId());
                PlayerLoginedDto p = new PlayerLoginedDto();
                BeanUtils.copyProperties(tplayer, p);
                if(tplayer.getBirth() != null)
                    p.setBirthStr(sdf.format(tplayer.getBirth()));
                players.add(p);
            }
            return new AjaxReturn<>(true, "success", players);
        }

    }

    @Override
    public Tplayer getPlayerByStudentId(String sId) {
        return playerDao.get("from Tplayer p where p.studentId = '"+sId+"'");
    }

    @Override
    public Tplayer getPlayerByStudentId(String sId, Short type) {
        return playerDao.get("from Tplayer p where p.studentId = '"+sId+"' and p.type ="+type);
    }

    @Override
    public Tplayer getPlayerByStudentIdStatus(String sId, Short status) {
        return playerDao.get("from Tplayer p where p.studentId = '"+sId+"' and p.status ="+status);
    }

    @Override
    public Tplayer getPlayerByStudentId(String sId, Short type, Short status) {
        return playerDao.get("from Tplayer p where p.studentId = '"+sId+"' and p.type = "+type+" and p.status ="+status);
    }

    @Override
    public List<Tplayer> getAllPlayer() {
        return playerDao.find("from Tplayer");
    }

    @Override
    public Long countPlayerByStudentId(String sId) {
        return playerDao.count("select count(*) from Tplayer p where p.studentId = '"+sId+"'");
    }

    @Override
    public Long countPlayerByStudentId(String sId, Short type) {
        return playerDao.count("select count(*) from Tplayer p where p.studentId = '"+sId+"' and p.type ="+type);
    }

    @Override
    public Long countPlayerByStudentIdStatus(String sId, Short status) {
        return playerDao.count("select count(*) from Tplayer p where p.studentId = '"+sId+"' and p.status ="+status);
    }

    @Override
    public Long countPlayerByStudentId(String sId, Short type, Short status) {
        return playerDao.count("select count(*) from Tplayer p where p.studentId = '"+sId+"' and p.type = "+type+" and p.status ="+status);
    }
}
